﻿using System.Windows.Input;

using Organizer.ViewModel;
using Organizer.Model;
using GalaSoft.MvvmLight.Command;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System;

namespace Organizer.Views
{
    public class NoteViewModel : BaseViewModel
    {
        private State status = State.Normal;

        public State Status
        {
            get { return status; }
            set
            {
                status = value;
                NotifyPropertyChanged(() => this.Status);
            }
        }

        private Note _noteToEdit;
        private Note _editedNote;

        public Note NoteToEdit
        {
            get
            {
                return this._noteToEdit ?? (this._noteToEdit = new Note());
            }

            set
            {
                _noteToEdit = value;
                NotifyPropertyChanged(() => this.NoteToEdit);
            }
        }
        public Note EditedNote
        {
            get
            {
                if (_editedNote == null)
                {
                    _editedNote = new Note();
                }
                return _editedNote;
            }
            set
            {
                _editedNote = value;
                NotifyPropertyChanged(() => this.EditedNote);
            }
        }

        public List<Note> Notes
        {
            get { return OrganizerDataContext.Instance.Notes.Where(n => n.Id != Guid.Empty).ToList(); }
        }

        public NoteViewModel()
        {
            NotifyPropertyChanged("Notes");
            this.AddCommand = new RelayCommand(() => AddNote());
            this.EditCommand = new RelayCommand<Note>(note => { EditNote(note); });
            this.SaveCommand = new RelayCommand(() => SaveNote());
            this.CancelCommand = new RelayCommand(() => CancelNote());
            this.RefreshCommand = new RelayCommand(() => RefreshNotes());
            this.DeleteNotesCommand = new RelayCommand(() => DeleteNotes());
            this.ManageCommand = new RelayCommand(() => ManageSelection());
            Status = State.Normal;
        }

        private void RefreshNotes()
        {
            this.NotifyPropertyChanged(() => this.Notes);
        }

        private void CancelNote()
        {
            Status = State.Normal;
            EditedNote = null;
            OrganizerDataContext.Instance.SubmitChanges();
            NotifyPropertyChanged(() => this.Notes);
        }

        private void SaveNote()
        {
            EditedNote.Assign(NoteToEdit);  
            
            if (!string.IsNullOrEmpty(NoteToEdit.Description))
            {
                if (!Notes.Contains(NoteToEdit))
                {
                    OrganizerDataContext.Instance.Notes.InsertOnSubmit(NoteToEdit);
                }
                OrganizerDataContext.Instance.SubmitChanges();
                Status = State.Normal;
                NotifyPropertyChanged(() => this.Notes);
            }
        }

        private void EditNote(Note note)
        {
            NoteToEdit = note;
            EditedNote = new Note();
            NoteToEdit.Assign(EditedNote);
            Status = State.Edit;
            NotifyPropertyChanged(() => this.EditedNote);
        }

        private void AddNote()
        {
            Status = State.Edit;
            EditedNote = new Note();
            NoteToEdit = new Note();
            NotifyPropertyChanged(() => this.Notes);
        }

        private void DeleteNotes()
        {
            var notes = new List<Note>();
            Notes.ForEach(x =>
            {
                if (x.IsSelectedMultiSelect)
                {
                    notes.Add(x);
                }
            });
            try
            {
                OrganizerDataContext.Instance.Notes.DeleteAllOnSubmit(notes);
                OrganizerDataContext.Instance.SubmitChanges();
            }
            catch
            {
                foreach (ObjectChangeConflict o in OrganizerDataContext.Instance.ChangeConflicts)
                {
                    o.Resolve(RefreshMode.KeepChanges);
                }
                OrganizerDataContext.Instance.SubmitChanges();
            }

            Status = State.Normal;
            NotifyPropertyChanged(() => this.Notes);
        }

        public void ManageSelection()
        {
            Status = State.ManageSelection;
            NotifyPropertyChanged(() => this.Notes);
        }

        public ICommand AddCommand { get; set; }
        public ICommand EditCommand { get; set; }
        public ICommand SaveCommand { get; set; }
        public ICommand CancelCommand { get; set; }
        public ICommand RefreshCommand { get; set; }
        public ICommand DeleteNotesCommand { get; set; }
        public ICommand ManageCommand { get; set; }
    }
}
